﻿//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#region << 版 本 注 释 >>

/*----------------------------------------------------------------
* 类 名 称 ：UIManager
* 类 描 述 ：
* 作    者 ：henrychang
* 创建时间 ：2019/1/5 15:05:18
*******************************************************************
* Copyright @ henrychang 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using EasyEditor;
using System.Collections.Generic;
using TouchFish.AssetLoad;
using TouchFish.SingletonClass;
using UnityEngine;
using UnityEngine.UI;

namespace TouchFish.UI
{
    public enum UILayer
    {
        AlwayBottom = -3, //如果不想区分太复杂那最底层的UI请使用这个
        Bg = -2, //背景层UI
        AnimationUnderPage = -1, //动画层
        Common = 0, //普通层UI
        AnimationOnPage = 1, // 动画层
        PopUI = 2, //弹出层UI
        Guide = 3, //新手引导层
        Const = 4, //持续存在层UI
        Toast = 5, //对话框层UI
        Forward = 6, //最高UI层用来放置UI特效和模型
        AlwayTop = 7, //如果不想区分太复杂那最上层的UI请使用这个
    }

    public class UIManager : SingletonMono<UIManager>, ISingleton
    {
        /// <summary>
        /// 存储所有加载的面板
        /// </summary>
        private Dictionary<uint, UIPanel> _allUI = new Dictionary<uint, UIPanel>();

        [Inspector(group = "Methods")]
        public void InitVariableData()
        {
            _bgTrans = transform.Find("Bg");
            _animationUnderTrans = transform.Find("AnimationUnder");
            _commonTrans = transform.Find("Common");
            _animationOnTrans = transform.Find("AnimationOn");
            _popUITrans = transform.Find("PopUI");
            _constTrans = transform.Find("Const");
            _toastTrans = transform.Find("Toast");
            _forwardTrans = transform.Find("Forward");
            mUICamera = transform.Find("UICamera").GetComponent<Camera>();
            mCanvas = transform.GetComponent<Canvas>();
            mCanvasScaler = transform.GetComponent<CanvasScaler>();
            mGraphicRaycaster = transform.GetComponent<GraphicRaycaster>();
        }

        [Inspector(group = "Variable")]
        [SerializeField] private Transform _bgTrans;

        [SerializeField] private Transform _animationUnderTrans;
        [SerializeField] private Transform _commonTrans;
        [SerializeField] private Transform _animationOnTrans;
        [SerializeField] private Transform _popUITrans;
        [SerializeField] private Transform _constTrans;
        [SerializeField] private Transform _toastTrans;
        [SerializeField] private Transform _forwardTrans;

        [SerializeField] private Camera mUICamera;
        [SerializeField] private Canvas mCanvas;
        [SerializeField] private CanvasScaler mCanvasScaler;
        [SerializeField] private GraphicRaycaster mGraphicRaycaster;

        public Canvas RootCanvas
        {
            get { return mCanvas; }
        }

        public Transform PopUI
        {
            get { return _popUITrans; }
        }

        public Camera UICamera
        {
            get { return mUICamera; }
        }

        public void SetResolution(int width, int height)
        {
            mCanvasScaler.referenceResolution = new UnityEngine.Vector2(width, height);
        }

        public void SetMatchOnWidthOrHeight(float heightPercent)
        {
            mCanvasScaler.matchWidthOrHeight = heightPercent;
        }

        public void OnSingletonInit()
        {
        }

        protected override void OnInitOrAwake()
        {
            base.OnInitOrAwake();
        }

        /// <summary>
        /// 打开UI
        /// </summary>
        /// <param name="uiResId">资源Id</param>
        /// <param name="canvasLayer">UI Layer</param>
        /// <param name="uiPanelData">数据层</param>
        /// <param name="assetBundleName">ab Name</param>
        /// <returns></returns>
        internal UIPanel OpenUI(uint uiResId)
        {
            // 如果缓存集合面板中不存在，则创建面板，加入缓存的集合
            if (!_allUI.ContainsKey(uiResId))
            {
                CreateUI(uiResId);
            }
            if (_allUI[uiResId].GetUIPanelInfo().UIPanelState != UIPanelState.Show)
                _allUI[uiResId].Show();
            else
                Debug.LogError(uiResId + "  this UIPanelState is show,you can not OpenUI");
            return _allUI[uiResId];
        }

        /// <summary>
        /// 隐藏UI
        /// </summary>
        /// <param name="uiResId">资源Id</param>
        internal void HideUI(uint uiResId)
        {
            UIPanel uiPanel = null;
            if (_allUI.TryGetValue(uiResId, out uiPanel))
            {
                if (_allUI[uiResId].GetUIPanelInfo().UIPanelState == UIPanelState.Show)
                    uiPanel.Hide();
                else
                    Debug.LogError(uiPanel.GetType().Name + "  this UIPanelState is not Show,you can not HideUI");
            }
        }

        /// <summary>
        /// 关闭并卸载UI
        /// </summary>
        /// <param name="uiResId">资源id</param>
        internal void CloseUI(uint uiResId)
        {
            UIPanel uiPanel = null;

            _allUI.TryGetValue(uiResId, out uiPanel);

            if (null != uiPanel)
            {
                if (uiPanel.Transform.gameObject.activeSelf)
                    uiPanel.Hide();
                uiPanel.DestoryUIPanel();
                _allUI.Remove(uiResId);
            }
        }

        /// <summary>
        /// 删除所有UI层
        /// </summary>
        internal void CloseAllUI()
        {
            foreach (var uiPanel in _allUI)
            {
                CloseUI(uiPanel.Value.GetUIPanelInfo().UIResId);
            }

            _allUI.Clear();
        }

        #region 创建

        /// <summary>
        /// 创建一个面板
        /// </summary>
        /// <param name="uiResId">资源Id</param>
        /// <returns></returns>
        private UIPanel CreateUI(uint uiResId)
        {
            UIPanel ui = CreateUIPanel(uiResId);
            _allUI.Add(uiResId, ui);
            ui.CreateUIPanel();
            return ui;
        }

        /// <summary>
        /// 创建UIPanel Object
        /// </summary>
        /// <param name="uiResId">资源Id</param>
        /// <param name="layer">UI Layer</param>
        /// <param name="assetBundleName">ab Name</param>
        /// <returns></returns>
        private UIPanel CreateUIPanel(uint uiResId)
        {
            UIPanel ui;
            string uiPath = ResBinData.Instance.GetUIPathById(uiResId).Path;
            ui = UIPanel.Load(uiPath);
            switch (ui.UIPanelType.Layer)
            {
                case UILayer.Bg:
                    ui.Transform.SetParent(_bgTrans);
                    break;

                case UILayer.AnimationUnderPage:
                    ui.Transform.SetParent(_animationUnderTrans);
                    break;

                case UILayer.Common:
                    ui.Transform.SetParent(_commonTrans);
                    break;

                case UILayer.AnimationOnPage:
                    ui.Transform.SetParent(_animationOnTrans);
                    break;

                case UILayer.PopUI:
                    ui.Transform.SetParent(_popUITrans);
                    break;

                case UILayer.Const:
                    ui.Transform.SetParent(_constTrans);
                    break;

                case UILayer.Toast:
                    ui.Transform.SetParent(_toastTrans);
                    break;

                case UILayer.Forward:
                    ui.Transform.SetParent(_forwardTrans);
                    break;
            }

            var uiGoRectTrans = ui.Transform as RectTransform;

            uiGoRectTrans.offsetMin = Vector2.zero;
            uiGoRectTrans.offsetMax = Vector2.zero;
            uiGoRectTrans.anchoredPosition3D = Vector3.zero;
            uiGoRectTrans.anchorMin = Vector2.zero;
            uiGoRectTrans.anchorMax = Vector2.one;

            ui.Transform.LocalScaleIdentity();
            ui.Transform.gameObject.name = uiResId + "_" + uiPath;

            return ui;
        }

        #endregion 创建
    }

    public static class UIMgr
    {
        public static Camera Camera
        {
            get { return UIManager.Instance.UICamera; }
        }

        /// <summary>
        /// 适配数据
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="matchOnWidthOrHeight"></param>
        public static void SetResolution(int width, int height, float matchOnWidthOrHeight)
        {
            UIManager.Instance.SetResolution(width, height);
            UIManager.Instance.SetMatchOnWidthOrHeight(matchOnWidthOrHeight);
        }

        public static void CloseAllPanel()
        {
            UIManager.Instance.CloseAllUI();
        }

        public static UIPanel OpenPanel(uint uiResId)
        {
            return UIManager.Instance.OpenUI(uiResId);
        }

        public static void HidePanel(uint uiResId)
        {
            UIManager.Instance.HideUI(uiResId);
        }

        public static void ClosePanel(uint uiResId)
        {
            UIManager.Instance.CloseUI(uiResId);
        }
    }
}